package org.taiolib.indicators;

import org.taiolib.Indicator;
import org.taiolib.indicators.movingAverage.MovingAverageType;
import org.taiolib.indicators.movingAverage.MAStrategy;
import org.taiolib.indicators.movingAverage.MAStrategyFactory;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.LinkedList;
import java.util.List;
import org.taiolib.exceptions.CeroParameterException;
import org.taiolib.exceptions.NotEnoughDataException;
import org.taiolib.exceptions.NullDataSerieException;
import org.taiolib.exceptions.NullParameterException;

/**
 *
 * @author Michael G. Langer
 */
public class MovingAverage implements Indicator {

    private MAStrategy strategy = null;

    private MathContext mContext = MathContext.DECIMAL32;

    public MovingAverage(MovingAverageType type) {
        changeMovingAverageType(type);
    }

    public List<BigDecimal> movingAverage(LinkedList<BigDecimal> inSerie, int value, int shift)
            throws NotEnoughDataException, NullDataSerieException, CeroParameterException {

        if (inSerie == null) {
            throw new NullDataSerieException("The values serie is null.");
        }
        if (inSerie.size() < value) {
            throw new NotEnoughDataException("The values serie is to short for this perios; " + inSerie + "|" + value);
        }
        if ( value == 0 ) {
            throw new CeroParameterException("The value parameter can not be cero.");
        }

        return strategy.movingAverage(inSerie, value, shift, mContext);
    }

    public void changeMovingAverageType(MovingAverageType type) {
       MAStrategyFactory masFactory = new MAStrategyFactory();
       strategy = masFactory.getMAStrategy(type);
    }

    public MovingAverageType getTypeOfMovingAverage() {
        return strategy.getType();
    }

    public void setMathContext(MathContext mathContext) throws NullParameterException {
        if ( mathContext == null ) {
            throw new NullParameterException("MathContext can not be null.");
        }
        mContext = mathContext;
    }

    public MathContext getMathContext() {
        return mContext;
    }

}
